package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/go-redis/redis"
	"io/ioutil"
	"net/http"
	"net/url"
	"reflect"
	"time"
)

type Controller struct {
	Response http.ResponseWriter
	Request  *http.Request
	Status   int
	values   url.Values
	URI      *url.URL
	Path     string

	Ip           string     // 客户端请求IP地址
	Form         url.Values // 客户端请求IP地址
	Resp         interface{}
	Err          interface{}
	PageSizeKey  string
	PageNumKey   string
	PageCountKey string
	PageNum      int
	PageSize     int
	Page         map[string]interface{}
	UserType     int    //用户类型
	UserId       string //用户类型
}

func (c *Controller) SetWR(w http.ResponseWriter, r *http.Request) {
	c.Request = r
	c.Response = w
	c.URI = r.URL
	c.values = c.URI.Query()
}
func (c *Controller) URIParam(param string) string {
	return c.values.Get(param)
}

func (c *Controller) ReadJSON(obj interface{}) (err error) {
	buf, err := ioutil.ReadAll(c.Request.Body)
	if err != nil {
		return
	}
	err = json.Unmarshal(buf, &obj)
	return
}
func (c *Controller) ToResp(status int, obj interface{}) (i int, err error) {
	response := c.Response
	response.WriteHeader(status)
	return response.Write(c.ToString(obj))
}

func (c *Controller) JSON(obj interface{}) (i int, err error) {
	c.ContentType("application/json; charset=utf-8")
	if c.Status != 0 {
		c.SetStatus(c.Status)
	}
	return c.Response.Write(c.ToString(obj))
} /*
func (c *Controller) RespSuccess(obj interface{}) (i int, err error) {
	//c.SetStatus(200)
	return c.JSON(obj)
}
func (c *Controller) RespError(obj interface{}) (i int, err error) {
	//c.SetStatus(200)
	return c.JSON(obj)
}*/

func (c *Controller) SetStatus(status int) {
	c.Response.WriteHeader(status)
}
func (c *Controller) ContentType(value string) {
	c.Response.Header().Set("Content-Type", value)
}

func (c *Controller) ToResp200(obj interface{}) (i int, err error) {
	return c.ToResp(200, obj)
}

func (c *Controller) ToResp500(obj interface{}) (i int, err error) {
	return c.ToResp(500, obj)
}

func (c *Controller) ToString(i interface{}) (b []byte) {
	var str string
	t := reflect.TypeOf(i)
	switch t.String() {
	case "int", "int64":
		str = fmt.Sprintf(`%d`, i)
		break
	case "float64", "float32":
		str = fmt.Sprintf(`%f`, i)
		break
	case "bool":
		if i.(bool) {
			str = "1"
		} else {
			str = "0"
		}
		break
	case "string":
		str = i.(string)
		break
	case "uint", "[]uint8":
		return i.([]byte)
	case "time.Duration":
		str = fmt.Sprintf(`%d`, int(i.(time.Duration)))
	default:
		b, _ = json.Marshal(i)
		return
	}
	return []byte(str)
}

type Setting struct {
	Name string `json:"name"`
	Addr string `json:"addr"`
	Port int    `json:"port"`
	Pass string `json:"pass"`

	SshIs   int    `json:"ssh_is"`
	SshAddr string `json:"ssh_addr"`
	SshAcc  string `json:"ssh_acc"`
	SshPort int    `json:"ssh_port"`
}

type Key struct {
	DB    int    `json:"db"`
	Name  string `json:"name"`
	T     string `json:"t"`
	Count int64  `json:"count"`
}

type Command struct {
	T       string                 `json:"t"` //类型
	C       string                 `json:"c"` //命令
	K       string                 `json:"k"` //键名
	F       string                 `json:"f"` //键名
	V       interface{}            `json:"v"` // 值
	E       int64                  `json:"e"` // 过期时间
	Vs      []interface{}          `json:"vs"`
	Section []string               `json:"vs"`
	Fs      map[string]interface{} `json:"fs"`
	Z       []redis.Z              `json:"z"`
}

func (c *Command) FunC() {
} // 命令

func (c *Controller) RespSuccess() {
	c.RespSuccessCM(200, "success")
}
func (c *Controller) RespSuccessD(data interface{}) {
	c.RespSuccessMD("success", data)
}
func (c *Controller) RespSuccessMD(msg string, data interface{}) {
	c.RespSuccessCMD(200, msg, data)
}
func (c *Controller) RespSuccessCM(code interface{}, msg string) {
	c.RespSuccessCMD(code, msg, nil)
}

func (c *Controller) RespSuccessCMD(code interface{}, msg string, data interface{}) {
	r := make(map[string]interface{})
	r["code"] = code
	r["msg"] = msg
	r["data"] = &data
	if c.Err == nil {
		if c.Resp == nil {
			c.Resp = r
			c.JSON(c.Resp)
		}
	}
}

func (c *Controller) RespError() {
	c.RespErrorCMD(500, "error", nil)
}
func (c *Controller) RespErrorD(data interface{}) {
	c.RespErrorCMD(500, "error", data)
}
func (c *Controller) RespErrorM(msg string) {
	c.RespErrorCMD(500, msg, nil)
}
func (c *Controller) RespErrorMD(msg string, data interface{}) {
	c.RespErrorCMD(500, msg, data)
}
func (c *Controller) RespErrorCM(code interface{}, msg string) {
	c.RespErrorCMD(code, msg, nil)
}
func (c *Controller) RespErrorCMD(code interface{}, msg string, data interface{}) {
	r := make(map[string]interface{})
	r["code"] = code
	r["msg"] = msg
	if data != nil {
		t := reflect.ValueOf(data)
		s := t.Type().String()
		if s == "*errors.fundamental" {
			t = reflect.Indirect(t)
			f0 := t.FieldByName("msg") //获取结构体s中第一个元素a
			r["data"] = f0.String()
		} else if s == "*pq.Error" {
			t = reflect.Indirect(t)
			f0 := t.FieldByName("msg") //获取结构体s中第一个元素a
			r["data"] = errors.New(f0.String())
		} else {
			r["data"] = data
		}
	}
	if c.Err == nil {
		c.Err = r
	}
	c.JSON(c.Err)
}
